/* 
 * Copyright (C) 2012 UTSChedule
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package utsc.apps.utschedule.ui.activities;
import greendroid.widget.QuickAction;
import greendroid.widget.QuickActionBar;
import greendroid.widget.QuickActionWidget;
import greendroid.widget.QuickActionWidget.OnQuickActionClickListener;

import java.text.DecimalFormat;
import java.util.ArrayList;

import utsc.apps.utschedule.R;
import utsc.apps.utschedule.classes.CourseMark;
import utsc.apps.utschedule.classes.UofTGrade;
import utsc.apps.utschedule.ui.activities.adapters.CalculatorPredictListAdapter;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Color;
import android.os.AsyncTask;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.Button;
import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;

import com.actionbarsherlock.app.SherlockFragmentActivity;
import com.actionbarsherlock.app.SherlockListFragment;
import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonParser;

/**
 * This is a custom list fragment that displays the list of {@link CourseMark
 * course marks} and calculate the GPA on the fly. It also saves all the entered
 * {@link CourseMark course marks} into {@link SharedPreferences} for easy data
 * storage.
 * 
 */
public class CalculatorPredictListFragment extends SherlockListFragment implements OnItemLongClickListener, OnQuickActionClickListener, OnClickListener{

	private CalculatorPredictListAdapter _adapter = null;
	private boolean _updated=true;
	private QuickActionBar _quickActionBar;
	private static final String COURSEMARK_SHAREDPREFERENCES="courseMarks";
	private final Gson _gson=new Gson();
	private int _selectedPosition=-99;
	private RelativeLayout _gpaView;
	private static final DecimalFormat DECIMAL_FORMAT = new DecimalFormat("###.##");
	private Button _btnClear;
	
	/**
	 * A delegate to allow {@link CalculatorPredictListFragment} to use its
	 * parent {@link SherlockFragmentActivity Activity} to handle the item click
	 * action.
	 * 
	 */
	public static interface OnCourseMarkSelectedListener{
		/**
		 * When the course mark item from the list is clicked.
		 * @param mark -the associated {@link CourseMark}
		 * @param position -the position of the item
		 */
		public void onCourseMarkItemClicked(CourseMark mark, int position);
	}
	
	@Override
	public void onActivityCreated(Bundle savedInstanceState) {
		super.onActivityCreated(savedInstanceState);
		getListView().setCacheColorHint(Color.TRANSPARENT);
		_quickActionBar=new QuickActionBar(getSherlockActivity());
		QuickAction _editAction=new QuickAction(getSherlockActivity(), R.drawable.ic_action_edit_alt, "Edit");
		QuickAction _deleteAction=new QuickAction(getSherlockActivity(), R.drawable.ic_action_delete_alt, "Delete");
		_quickActionBar.addQuickAction(_editAction);
		_quickActionBar.addQuickAction(_deleteAction);
		_quickActionBar.setOnQuickActionClickListener(this);
		_gpaView=(RelativeLayout)getView().findViewById(R.id.gpa_view);
		_btnClear=(Button)_gpaView.findViewById(R.id.btn_clear);
		_btnClear.setOnClickListener(this);
		new StartUpTask(getSherlockActivity(), this).execute();
	}
	
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setHasOptionsMenu(true);
	}
	
	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		return inflater.inflate(R.layout.fragment_calculator_prediction_list, null);
	}

	/**
	 * A callback method that can be used to update the given course mark item in the list.
	 * @param courseMark -the given {@code CourseMark}
	 * @param position -the given position of the item
	 */
	public void updateCourseMark(CourseMark courseMark, int position){
		if (_adapter!=null) {
			SharedPreferences courseMarkPreferences=getSherlockActivity().getSharedPreferences(COURSEMARK_SHAREDPREFERENCES, SherlockFragmentActivity.MODE_PRIVATE);
			_adapter.setItem(courseMark, position);
			courseMarkPreferences.edit().putString(COURSEMARK_SHAREDPREFERENCES,_gson.toJson(_adapter.get_courseMarks())).commit();
			refreshGPA();
		}
	}
	
	/**
	 * Recalculate the gpa on the fly.
	 */
	public void refreshGPA() {
		if (_adapter!=null) {
			ArrayList<CourseMark> courseMarks=_adapter.get_courseMarks();
			double totalCourseWeight=0;
			double totalCourseMark=0;
			if (courseMarks!=null && !courseMarks.isEmpty()) {
				UofTGrade tempGrade=new UofTGrade(0, 100, 0);
				for (CourseMark courseMark : courseMarks) {
					tempGrade.set_marks(courseMark.get_mark());
					tempGrade.calculatePercentage();
					totalCourseWeight+=courseMark.get_weight();
					totalCourseMark+=courseMark.get_weight()*tempGrade.get_GPA();
				}
			}else {
				totalCourseWeight=0.5;
			}
			((TextView)_gpaView.findViewById(R.id.txt_list_gpa)).setText(String.valueOf(DECIMAL_FORMAT.format(totalCourseMark/totalCourseWeight)));
		}
		
	}
	
	/**
	 * A callback method that can be used when a {@link StartUpTask} is completed.
	 * @param courseMarks
	 */
	public void onStartUpCompleted(ArrayList<CourseMark> courseMarks) {
		_adapter=new CalculatorPredictListAdapter(getSherlockActivity(), R.layout.course_prediction_list_item, courseMarks);
		refreshGPA();
		setListAdapter(_adapter);
		getListView().setOnItemLongClickListener(this);
	}
	
	@Override
	public void onActivityResult(int requestCode, int resultCode, Intent data) {
		super.onActivityResult(requestCode, resultCode, data);
		if (resultCode==SherlockFragmentActivity.RESULT_OK){
			_updated=false;
		}
	}
	
	@Override
	public void onListItemClick(ListView parent, View v, int position, long id) {
		_selectedPosition=position;
		((OnCourseMarkSelectedListener)getSherlockActivity()).onCourseMarkItemClicked(_adapter.getItem(_selectedPosition), _selectedPosition);
	}

	@Override
	public void onQuickActionClicked(QuickActionWidget widget, int position) {
		//there are only two quick actions, either edit or delete	
		if (position==0) {
				((OnCourseMarkSelectedListener)getSherlockActivity()).onCourseMarkItemClicked(_adapter.getItem(_selectedPosition), _selectedPosition);
			}else {
				_adapter.get_courseMarks().remove(_selectedPosition);
				_adapter.notifyDataSetChanged();
				SharedPreferences courseMarkPreferences=getSherlockActivity().getSharedPreferences(COURSEMARK_SHAREDPREFERENCES, SherlockFragmentActivity.MODE_PRIVATE);
				courseMarkPreferences.edit().putString(COURSEMARK_SHAREDPREFERENCES,_gson.toJson(_adapter.get_courseMarks())).commit();
				refreshGPA();
				Toast.makeText(getSherlockActivity(), "Course mark is deleted.", Toast.LENGTH_SHORT).show();
			}
		widget.dismiss();
	}

	@Override
	public boolean onItemLongClick(AdapterView<?> adapterView, View view, int position,
			long id) {
		//on long click, show the quick action 
		final CourseMark courseMark=_adapter.getItem(position);
		if (courseMark!=null) {
			_selectedPosition=position;
			_quickActionBar.show(view);
		}
		
		return true;
	}
	
	/**
	 * AsyncTask that reads all the {@link CourseMark marks} from the {@link SharedPreferences}. 
	 */
	private static class StartUpTask extends AsyncTask<Void, Void, ArrayList<CourseMark>>{
		private Context _context;
		private final Gson _gson=new Gson();
		private CalculatorPredictListFragment _fragment;
		protected StartUpTask(Context context, CalculatorPredictListFragment fragment){
			this._context=context;
			this._fragment=fragment;
		}
		
		@Override
		protected ArrayList<CourseMark> doInBackground(Void... params) {
			SharedPreferences courseMarkPreferences=_context.getSharedPreferences(COURSEMARK_SHAREDPREFERENCES, SherlockFragmentActivity.MODE_PRIVATE);
			String courseMarksJSON=courseMarkPreferences.getString(COURSEMARK_SHAREDPREFERENCES,null);
			ArrayList<CourseMark> _courseMarks = new ArrayList<CourseMark>();
			if (!TextUtils.isEmpty(courseMarksJSON)) {
				JsonParser parser=new JsonParser();
				JsonArray courseMarkJsonArray=parser.parse(courseMarksJSON).getAsJsonArray();
				for (JsonElement jsonElement : courseMarkJsonArray) {
					_courseMarks.add(_gson.fromJson(jsonElement, CourseMark.class));
				}
			}
			return _courseMarks;
		}
		
		@Override
		protected void onPostExecute(ArrayList<CourseMark> result) {
			_fragment.onStartUpCompleted(result);
		}
	}

	@Override
	public void onClick(View v) {
		switch (v.getId()) {
		//handle the clear button click action
		case R.id.btn_clear:
			if (_adapter!=null) {
				//simply clear all the course marks
				//and clear the sharedpreferences
				_adapter.get_courseMarks().clear();
				_adapter.notifyDataSetChanged();
				SharedPreferences courseMarkPreferences=getSherlockActivity().getSharedPreferences(COURSEMARK_SHAREDPREFERENCES, SherlockFragmentActivity.MODE_PRIVATE);
				courseMarkPreferences.edit().remove(COURSEMARK_SHAREDPREFERENCES).commit();
				refreshGPA();
			}
			break;

		default:
			break;
		}
	}

}
